package gggameserver.compiler;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import gggameserver.exceptions.GGProcessException;
import gggameserver.games.connection.ProcessConnection;
import gggameserver.util.GGConfiguration;
import gggameserver.util.GGUtil;

public class GGCompiler {
	
	String language = null;
	ArrayList files = null;
	File dir = null;
public	String relativeDir = null;
	
	public GGCompiler(String lang, File dir, String relativeDir) {
		// TODO check file and dir
		this.language = lang;
		this.dir = dir;
		this.relativeDir = relativeDir;
	}
	
	public ArrayList<ArrayList<String>> getCompilerCommands() {
		ArrayList<ArrayList<String>> res = new ArrayList<ArrayList<String>>();
		if (this.language.equalsIgnoreCase("c++")) {
			ArrayList cmdarray = new ArrayList();
			cmdarray.add("g++");
			cmdarray.add("-o");
			cmdarray.add("a.exe");
			String[] extensions = {".cpp"};
			appendFiles(cmdarray, extensions);
			
			res.add(cmdarray);
		} else if (this.language.equalsIgnoreCase("c++ -O3")) {
			ArrayList cmdarray = new ArrayList();
			cmdarray.add("g++");
			cmdarray.add("-O3");
			cmdarray.add("-o");
			cmdarray.add("a.exe");
			String[] extensions = {".cpp"};
			appendFiles(cmdarray, extensions);
			
			res.add(cmdarray);
		} else if (this.language.equalsIgnoreCase("FreePascal")) {
			ArrayList cmdarray = new ArrayList();
			cmdarray.add("fpc");
			cmdarray.add("-oa.exe");
			cmdarray.add("Lahing2011.pas");
			//String[] extensions = {".pas"};
			//appendFiles(cmdarray, extensions);
			
			res.add(cmdarray);
		} else if (this.language.equalsIgnoreCase("java")) {
			ArrayList cmdarray = new ArrayList();
			cmdarray.add("javac");
			String[] extensions = {".java"};
			appendFiles(cmdarray, extensions);
			
			res.add(cmdarray);
		} else if (this.language.equalsIgnoreCase("haskell")) {
			ArrayList cmdarray = new ArrayList();
			cmdarray.add("ghc");
			cmdarray.add("-O");
			cmdarray.add("--make");
			cmdarray.add("-o");
			cmdarray.add("a.exe");
			cmdarray.add("Lahing2011.hs");
			
			res.add(cmdarray);
		} else if (this.language.equalsIgnoreCase("python")) {
			ArrayList cmdarray = new ArrayList();
			//cmdarray.add("python");
			//cmdarray.add("-c");
			//cmdarray.add("import compileall; compileall.compile_dir('.', force=True, quiet=True)");
			
			cmdarray.add("python");
			cmdarray.add("-c");
			cmdarray.add("import py_compile;py_compile.compile('__init__.py')"); 
			cmdarray.add(".");
			
			res.add(cmdarray);
			
			cmdarray = new ArrayList<String>();
			cmdarray.add("python");
			cmdarray.add("-m");
			cmdarray.add("compileall"); 
			cmdarray.add(".");
			
			res.add(cmdarray);
		} else {
			throw new IllegalStateException("Illegal language: '" + this.language + "'");
		}
		
		return res;
	}
	
	public void compile() throws IOException, GGProcessException {
		ArrayList<ArrayList<String>> cmds = getCompilerCommands();
		for (ArrayList<String> cmdarray : cmds)
			runCompiler(cmdarray);
	}
	
	private void appendFiles(ArrayList cmdarray, String[] extensions) {
		files = GGUtil.filterFiles(GGUtil.getFileList(dir), extensions);
		for (int i = 0; i < files.size(); i++)
			cmdarray.add(files.get(i));
	}
	
	private void runCompiler(ArrayList cmdarray) throws IOException, GGProcessException {
		Process compiler = GGUtil.exec(cmdarray, this.dir);
		
		String output = GGUtil.collectOutput(compiler);
System.out.println("out:\"" + output + "\"");
		
		if (compiler.exitValue() != 0)
			throw new GGProcessException("Error while compiling solution.", cmdarray, compiler.exitValue(), output);
	}
	
	public ArrayList getProgramsCommand() throws IOException {
		ArrayList cmdarray = new ArrayList();
		if (   this.language.equalsIgnoreCase("c++")
			|| this.language.equalsIgnoreCase("c++ -O3")
			|| this.language.equalsIgnoreCase("FreePascal")
			|| this.language.equalsIgnoreCase("haskell"))
		{
//			String dirdir = null;
//			if (GGConfiguration.isWindows()) dirdir = dir.getPath();
//			else dirdir = "./";
// TODO
//			String exe = (new File(dirdir, "a.exe")).getPath();
			String exe = "./a.exe";
System.out.println("exe = " + exe);
			cmdarray.add(exe);
		} else if (this.language.equalsIgnoreCase("java")) {
			cmdarray.add("java");
			cmdarray.add("Program");
		} else if (this.language.equalsIgnoreCase("python")) {
			cmdarray.add("python");
			cmdarray.add("-u");
			cmdarray.add("__init__.py");
		} else {
			throw new IllegalStateException("Illegal language: '" + this.language + "'");
		}
		return cmdarray;
		//return new ProcessConnection(cmdarray, new File(dir));
	}
	
	public File getProgramsDirectory() throws IOException {
		return dir;
	}
	
}
